package com.mcptt.config;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.cloudptt.api.product.log.Log;
import com.mcptt.comm.CommonFunc;
import com.mcptt.config.callback.IParserCallback;
import com.mcptt.db.DBAdapter;
import com.mcptt.db.model.ConfigFileInfo;
import com.mcptt.http.operator.HttpOperator;
import com.mcptt.notify.xcap.XcapDoc;

import java.io.InputStream;

import okhttp3.Response;

public abstract class AbstractConfigFile implements IDbOperation,ISvrOperation
{
	protected final static int OP_SUC = 0;
	protected final static int OP_FAILED = 1;
	
	protected final static String Key_FileName = "FileName";
	protected final static String Key_ErrStr = "ErrStr";

	protected DBAdapter dbOperator = null;
	protected ConfigFileInfo info = null;
	protected IParserCallback callback = null;

	public AbstractConfigFile(DBAdapter dbOperator)
	{
		this.dbOperator = dbOperator;
	}

	protected Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			String fileName = null;
			switch(msg.what)
			{
			case OP_SUC:
				fileName = msg.obj.toString();
				if(callback != null)
				{
					callback.parserFileSuc(fileName);
				}
				break;
			case OP_FAILED:
				Bundle obj = (Bundle)msg.obj;
				fileName = obj.getString(Key_FileName);
				String errStr = obj.getString(Key_ErrStr);
				if(callback != null)
				{
					callback.parserFileFailed(fileName,errStr);
				}
				break;
			}
		}
	};
	@Override  
	public void runReadFromSvrThread(final XcapDoc doc,final String rootPath,final String accessToken,IParserCallback parserCallback)
	{
		Log.debug(getClass(), "runReadFromSvrThread doc = " + doc + " rootPath = " + rootPath + " accessToken = " + accessToken);
		this.callback = parserCallback;
		Runnable runnable = new Runnable(){
			@Override
			public void run() {
				// TODO: http request.
				try
				{
					readFromSvr(doc,rootPath,accessToken);
				} catch (Exception ex)
				{
					// TODO Auto-generated catch block
					ex.printStackTrace();
					String fileName = doc.getFileName();
					sendOpFailedMsg(fileName,"readFromSvr Exception = " + ex);
				}
			}
		};
		new Thread(runnable).start();
	}

	private void readFromSvr(XcapDoc doc,String rootPath,String accessToken) throws Exception
	{
		// TODO Auto-generated method stub
		Log.debug(getClass(), "readFromSvr doc = " + doc + " rootPath = " + rootPath + " accessToken = " + accessToken);
		String subPath = doc.getSel();
		Log.debug(getClass(), "readFromSvr rootPath = " + rootPath + " subPath = " + subPath);
		if(!subPath.startsWith("/"))
		{
			subPath = "/"+ subPath;
		}
		String path = rootPath +subPath;
		Log.debug(getClass(), "readFromSvr path = " + path);
		String fileName = doc.getFileName();
		HttpOperator operator = new HttpOperator();

		Response response = null;
		if(accessToken != null)
		{
			response = operator.httpGetRequestByAccessToken(path, accessToken);
		}
		else
		{
			response = operator.httpGetRequest(path);
		}
		if(response == null)
		{
			sendOpFailedMsg(fileName,"" + fileName+ "readFromSvr response == null");
		}
		int code = response.code();
		Log.debug(getClass(), "" + fileName + "readFromSvr code = " + code);
		if(code == 200)
		{
			InputStream instreams = response.body().byteStream();
			String content = CommonFunc.convertStreamToString(instreams);
			Log.debug(getClass(), "Content = " + content);

			String eTag = doc.getNewEtag();
			this.info = new ConfigFileInfo(fileName,eTag,content);
			parse(info);
			syncToDb(info);
			saveInfoToDb();
			sendOpSucMsg(fileName);
		}
		else
		{
			sendOpFailedMsg(fileName, "code = " + code);
		}
	}

	private void sendOpSucMsg(String fileName)
	{
		Log.debug(getClass(), "sendOpSucMsg = " + fileName);
		Message msg = handler.obtainMessage(OP_SUC, fileName);
		msg.sendToTarget();
	}
	
	private void sendOpFailedMsg(String fileName,String errStr)
	{
		Log.debug(getClass(), "sendOpFailedMsg = " + fileName + " errStr = " + errStr);
		Bundle obj = new Bundle();
		obj.putString(Key_FileName, fileName);
		obj.putString(Key_ErrStr, errStr);
		Message msg = handler.obtainMessage(OP_FAILED, obj);
		msg.sendToTarget();
	}
	
	protected void notifyFailed(IParserCallback callback,String fileName,String errStr)
	{
		if(callback != null)
		{
			callback.parserFileFailed(fileName,errStr);
		}
	}

	@Override
	public ConfigFileInfo readFromDb(String fileName)
	{
		// TODO Auto-generated method stub
//		Log.debug(getClass(), "readFromDb fileName = " + fileName);
//		this.info = dbOperator.getConfigFileInfoByFileName(fileName);
//		if(info == null)
//		{
//			Log.debug(getClass(), "readFromDb fileName = " + fileName  + " info = null");
//		}
//		return info;
		return null;
	}

	@Override
	public void syncToDb(ConfigFileInfo info)
	{
		// TODO Auto-generated method stub
		Log.debug(getClass(), "syncToDb info = " + info);
		dbOperator.addConfigFileInfo(info);
	}
	abstract public void parse(ConfigFileInfo info);
	abstract public boolean checkMustParamOk();
}
